/**********************************************************************************
 * Copyright (c) 2012 - 2012,  quick_tools, All right reserved
 * Title: com.adc.quicktools  ObjectUtil.java 
 * @author shen  shenqiao2012@163.com 
 *  2012-7-1 下午11:26:27 
 *********************************************************************************/


package com.adc.quicktools;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;





public class ObjectUtil {
	
	/**
	 * 
	 * Description: 将object数组拼装成字符串并返回，每个值之间的间隔由gap确定；
	 * author:  shen
	 * @param array
	 * @param gap 可以为“”，表示无间隔
	 * @return String
	 */
	public static String arrayToString(Object[] array,String gap) {
		StringBuffer sBuffer=new StringBuffer();
		if (array!=null&&gap!=null&&array.length>0) {
			for (Object obj : array) {
				sBuffer.append(obj+gap);
			}
		}
		return sBuffer.toString();
	}
	
	/**
	 * 
	 * Description: 判断两个对象相等；1、fields 数量相等；2、方法数目相等；3、field的值相等（通过getter判断）；
	 * 该方法只对简单类型如int、Long、String、boolean进行判断，如果需要进行其他类型的判断，可以继承该类进行对象的比较。
	 * author:  shen
	 * @param obj1  对象1
	 * @param obj2  对象2
	 * @return boolean 如果相等，则返回true，反之返回false；
	 */
	public static boolean objectEquals(Object obj1, Object obj2) {
		//TODO test processing time;
		Long st,ed;
		st=new Date().getTime();
		boolean equal = false;
		if (obj1 != null && obj2 != null) {
			Field[] fields1=obj1.getClass().getDeclaredFields();
			Field[] fields2=obj2.getClass().getDeclaredFields();
			Method[] methods1 = obj1.getClass().getDeclaredMethods();
			Method[] methods2 = obj2.getClass().getDeclaredMethods();
			if (fields1.length-fields2.length==0 ) {
				if (methods1.length-methods2.length==0) {
					for (int i = 0; i < methods1.length; i++) {
						if ( methods1[i].getModifiers()==1 &&
								methods2[i].getModifiers()==1 ) {
							if (methods1[i].getParameterTypes().length == 0 &&
									methods1[i].getReturnType().equals(int.class) &&
									methods2[i].getParameterTypes().length == 0 &&
									methods2[i].getReturnType().equals(int.class)) {
								int val1;
								int val2;
								try {
									val1 = (Integer) methods1[i].invoke(obj1);
									val2 = (Integer) methods2[i].invoke(obj2);
									if ((val1 - val2) != 0) {
										equal = false;
										break;
									} else {
										equal = true;
									}
									//						System.err.println(val1+"---||---"+val2);
								} catch (IllegalArgumentException e) {
									e.printStackTrace();
								} catch (IllegalAccessException e) {
									e.printStackTrace();
								} catch (InvocationTargetException e) {
									e.printStackTrace();
								}
							} else if (methods1[i].getParameterTypes().length == 0
									&& methods1[i].getReturnType().equals(long.class) &&
									methods2[i].getParameterTypes().length == 0
									&& methods2[i].getReturnType().equals(long.class)) {
								Long val1;
								Long val2;
								try {
									val1 = (Long) methods1[i].invoke(obj1);
									val2 = (Long) methods2[i].invoke(obj2);
									if ((val1 - val2) != 0) {
										equal = false;
										break;
									} else {
										equal = true;
									}
									//						System.err.println(val1+"---||---"+val2);
								} catch (IllegalArgumentException e) {
									e.printStackTrace();
								} catch (IllegalAccessException e) {
									e.printStackTrace();
								} catch (InvocationTargetException e) {
									e.printStackTrace();
								}
							} else if (methods1[i].getParameterTypes().length == 0
									&& methods1[i].getReturnType().equals(String.class) &&
									methods2[i].getParameterTypes().length == 0
									&& methods2[i].getReturnType().equals(String.class)) {
								String val1;
								String val2;
								try {
									val1 = (String) methods1[i].invoke(obj1);
									val2 = (String) methods2[i].invoke(obj2);
									if (val1 == null || val2 == null) {
										if (val1 == null && val2 == null) {
											equal = true;
										} else {
											equal = false;
											break;
										}
									} else if (val1.equals(val2) && val2.equals(val1)) {
										equal = true;
									} else {
										equal = false;
										System.out.println(val1 + "~~" + val2);
										break;
									}
									//						System.err.println(val1+"---||---"+val2);
								} catch (IllegalArgumentException e) {
									e.printStackTrace();
								} catch (IllegalAccessException e) {
									e.printStackTrace();
								} catch (InvocationTargetException e) {
									e.printStackTrace();
								}
							}
							if (methods1[i].getParameterTypes().length == 0
									&& methods1[i].getReturnType().equals(boolean.class) &&
									methods2[i].getParameterTypes().length == 0
									&& methods2[i].getReturnType().equals(boolean.class)) {
								boolean val1;
								boolean val2;
								try {
									val1 = (Boolean) methods1[i].invoke(obj1);
									val2 = (Boolean) methods2[i].invoke(obj2);
									if (val1 && val2) {
										equal = true;
									} else if (!val1 && !val2) {
										equal = true;
									} else {
										equal = false;
										break;
									}
									//						System.err.println(val1+"---||---"+val2);
								} catch (IllegalArgumentException e) {
									e.printStackTrace();
								} catch (IllegalAccessException e) {
									e.printStackTrace();
								} catch (InvocationTargetException e) {
									e.printStackTrace();
								}
							}
						}

					}
				}
			}
			
		}else if(obj1==null && obj2==null){
			equal=true;
		}
		//TODO print processing time;
		ed=new Date().getTime();
//		System.out.println((ed-st)+"*10^(-3)s");
		return equal;
	}
	
	/**
	 * 
	 * Description: 判断两个对象相等；1、fields 数量相等；2、方法数目相等；
	 * 3、field的值相等（通过getter判断只将没有参数，且get对应标准字段名取出进行值的比较）；
	 * 该方法只对简单类型如int、Long、String、boolean进行判断，如果需要进行其他类型的判断，可以继承该类进行对象的比较。
	 * 推荐使用该方法，效率能比objectEquals平均快2倍左右。
	 * author:  shen
	 * @param obj1  对象1
	 * @param obj2  对象2
	 * @return boolean 如果相等，则返回true，反之返回false；
	 */
	public static boolean objectEquals2(Object obj1, Object obj2) {
		//TODO test processing time;
		Long st,ed;
		st=new Date().getTime();
		boolean equal = false;
		if (obj1 != null && obj2 != null) {
			Field[] fields1=obj1.getClass().getDeclaredFields();
			Field[] fields2=obj2.getClass().getDeclaredFields();
			Method[] methods1 = obj1.getClass().getDeclaredMethods();
			Method[] methods2 = obj2.getClass().getDeclaredMethods();
			if (fields1.length-fields2.length==0 ) {
				if (methods1.length-methods2.length==0) {
					for (int i = 0; i < methods1.length; i++) {
						String tmp1 = null,tmp2=null;
						String flag1="",flag2="";
						if (methods1[i].getName().startsWith("is")){
							flag1="is";
							tmp1 = StringUtil.lowerFirst(methods1[i].getName().substring(2));							
						} else if (methods1[i].getName().startsWith("get")){
							flag1="get";
							tmp1 = StringUtil.lowerFirst(methods1[i].getName().substring(3));
						}
						if (methods2[i].getName().startsWith("is")){
							flag2="is";
							tmp2 = StringUtil.lowerFirst(methods2[i].getName().substring(2));
						} else if (methods2[i].getName().startsWith("get")){
							flag2="get";
							tmp2 = StringUtil.lowerFirst(methods2[i].getName().substring(3));
						}
//						System.out.println(tmp1+"  "+tmp2);
						if (tmp1!=null&&tmp2!=null&&
								methods1[i].getModifiers()==1 &&
								methods2[i].getModifiers()==1 &&
								tmp1.equals(tmp2)) {
							Method tempMethod1=null,tempMethod2=null;
							try {
								tempMethod1=obj1.getClass().getMethod(flag1+ StringUtil.upperFirst(tmp1));
								tempMethod2=obj2.getClass().getMethod(flag2 + StringUtil.upperFirst(tmp2));
							} catch (SecurityException e1) {
								e1.printStackTrace();
							} catch (NoSuchMethodException e1) {
								e1.printStackTrace();
							}
							if (tempMethod1!=null&&tempMethod2!=null) {
								if (tempMethod1.getParameterTypes().length == 0 &&
										tempMethod1.getReturnType().equals(int.class) &&
										tempMethod2.getParameterTypes().length == 0 &&
										tempMethod2.getReturnType().equals(int.class)) {
									int val1;
									int val2;
									try {
										val1 = (Integer) tempMethod1.invoke(obj1);
										val2 = (Integer) tempMethod2.invoke(obj2);
										if ((val1 - val2) != 0) {
											equal = false;
											break;
										} else {
											equal = true;
										}
									} catch (IllegalArgumentException e) {
										e.printStackTrace();
									} catch (IllegalAccessException e) {
										e.printStackTrace();
									} catch (InvocationTargetException e) {
										e.printStackTrace();
									}
								} else if (tempMethod1.getParameterTypes().length == 0
										&& tempMethod1.getReturnType().equals(long.class) &&
										tempMethod2.getParameterTypes().length == 0
										&& tempMethod2.getReturnType().equals(long.class)) {
									Long val1;
									Long val2;
									try {
										val1 = (Long) tempMethod1.invoke(obj1);
										val2 = (Long) tempMethod2.invoke(obj2);
										if ((val1 - val2) != 0) {
											equal = false;
											break;
										} else {
											equal = true;
										}
									} catch (IllegalArgumentException e) {
										e.printStackTrace();
									} catch (IllegalAccessException e) {
										e.printStackTrace();
									} catch (InvocationTargetException e) {
										e.printStackTrace();
									}
								} else if (tempMethod1.getParameterTypes().length == 0
										&& tempMethod1.getReturnType().equals(String.class) &&
										tempMethod2.getParameterTypes().length == 0
										&& tempMethod2.getReturnType().equals(String.class)) {
									String val1;
									String val2;
									try {
										val1 = (String) tempMethod1.invoke(obj1);
										val2 = (String) tempMethod2.invoke(obj2);
										if (val1 == null || val2 == null) {
											if (val1 == null && val2 == null) {
												equal = true;
											} else {
												equal = false;
												break;
											}
										} else if (val1.equals(val2) && val2.equals(val1)) {
											equal = true;
										} else {
											equal = false;
											System.out.println(val1 + "~~" + val2);
											break;
										}
									} catch (IllegalArgumentException e) {
										e.printStackTrace();
									} catch (IllegalAccessException e) {
										e.printStackTrace();
									} catch (InvocationTargetException e) {
										e.printStackTrace();
									}
								}
								if (tempMethod1.getParameterTypes().length == 0
										&& tempMethod1.getReturnType().equals(boolean.class) &&
										tempMethod2.getParameterTypes().length == 0
										&& tempMethod2.getReturnType().equals(boolean.class)) {
									boolean val1;
									boolean val2;
									try {
										val1 = (Boolean) tempMethod1.invoke(obj1);
										val2 = (Boolean) tempMethod2.invoke(obj2);
										if (val1 && val2) {
											equal = true;
										} else if (!val1 && !val2) {
											equal = true;
										} else {
											equal = false;
											break;
										}
									} catch (IllegalArgumentException e) {
										e.printStackTrace();
									} catch (IllegalAccessException e) {
										e.printStackTrace();
									} catch (InvocationTargetException e) {
										e.printStackTrace();
									}
								}
							}
						} // 根据tmp获取反射方法
						

					}
				}
			}
			
		}else if(obj1==null && obj2==null){
			equal=true;
		}
		//TODO print processing time;
		ed=new Date().getTime();
//		System.out.println((ed-st)+"*10^(-3)s");
		return equal;
	}
	
	
	/**
	 * 
	 * Description: 调用指定对象的指定field的getter
	 * author:  shen
	 * @param obj 指定的对象
	 * @param att 指定的field
	 * @return Object
	 */
	public static Object getter(Object obj, String att) {
		Object result = null;
		try {
			Method method = obj.getClass().getMethod("get" + StringUtil.upperFirst(att));
			System.out.println(att+"="+method.invoke(obj));
			result=method.invoke(obj);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 
	 * Description: 调用指定对象的指定field的setter
	 * author:  shen
	 * @param obj 指定对象
	 * @param att 指定的field
	 * @param value 传入的值
	 * @param type 参数的属性
	 * @return void
	 */
	public static void setter(Object obj, String att, Object value,Class<?> type) {
		try {
			Method method = obj.getClass().getMethod("set" + StringUtil.upperFirst(att), type);
			method.invoke(obj, value);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}

	}

}
